package com.obelisco.vista.seguridad;

import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Vector;

import com.obelisco.exception.ObeliscoException;
import com.obelisco.modelo.data.Operacion;
import com.obelisco.vista.componentes.ComponenteDatosListener;
import com.obelisco.vista.componentes.DialogoError;
import com.obelisco.vista.componentes.TipoFuncion;
import com.obelisco.vista.util.BarraHerramientasHelper;

import nextapp.echo2.app.ContentPane;
import nextapp.echo2.app.Button;
import echopointng.ContainerEx;
import echopointng.ExtentEx;
import echopointng.layout.DisplayLayoutData;
import nextapp.echo2.app.Component;
import nextapp.echo2.app.SplitPane;
import nextapp.echo2.app.Extent;
import nextapp.echo2.app.Row;
import nextapp.echo2.app.Alignment;
import nextapp.echo2.app.ResourceImageReference;
import nextapp.echo2.app.event.ActionEvent;
import nextapp.echo2.app.event.ActionListener;

public class PaneDatosBase extends ContentPane {

	private ResourceBundle resourceBundle;

	private Object objetoAnterior = null;

	private Object objeto = null;

	private Map<String, ComponenteDatosListener> paneles = new HashMap<String, ComponenteDatosListener>();

	private Button btnAceptar;

	private Button btnCancelar;

	private ContainerEx paneContenido;

	private boolean conCache = true;

	private Vector<PaneDatosListener> listeners = new Vector<PaneDatosListener>();

	/**
	 * Creates a new <code>PaneDatosBase2</code>.
	 */
	public PaneDatosBase() {
		super();

		// Add design-time configured components.
		initComponents();
	}

	private Component buscarPanelDatos(String clase) {

		Component panel = null;

		if (paneles.containsKey(clase)) {

			ComponenteDatosListener componenteDatos = paneles.get(clase);

			if (componenteDatos instanceof Component) {
				Component componente = (Component) componenteDatos;

				DisplayLayoutData layoutData = new DisplayLayoutData();
				layoutData.setHeight(new ExtentEx("100%"));
				layoutData.setWidth(new ExtentEx("100%"));

				componente.setLayoutData(layoutData);

				panel = componente;

			}

		}

		return panel;

	}

	private void cambiarEstadoBotones(boolean estado) {

		btnAceptar.setEnabled(estado);
		btnCancelar.setEnabled(estado);

	}

	public void onIncluirObjeto(Object objeto) {

		this.objetoAnterior = this.objeto;
		onObjetoEntidad(objeto);
		activarCambios(TipoFuncion.INCLUIR, BarraHerramientasHelper.getFuncion(
				TipoFuncion.INCLUIR).getNombre());

	}

	public void onObjetoEntidad(Object objeto) {

		this.objeto = objeto;
		String nombreClase = objeto.getClass().getName();

		Component componente = buscarPanelDatos(nombreClase);
		if (componente != null) {

			paneContenido.removeAll();
			paneContenido.add(componente);

			ComponenteDatosListener componenteDatos = (ComponenteDatosListener) componente;

			tipoFuncionActual = TipoFuncion.BUSCAR;
			nombreFuncionActual = BarraHerramientasHelper.getFuncion(
					tipoFuncionActual).getNombre();

			try {

				componenteDatos.onObjetoEntidad(objeto);
				componenteDatos.onInicializar();
				componenteDatos.onConsultar(objeto);
				cambiarEstadoBotones(false);

			} catch (ObeliscoException obex) {
				if (obex.getNumError() > 0) {
					DialogoError.mostrar("Error", obex.getNumError());
				} else {
					DialogoError.mostrar("Error", obex.getMessage());
				}
			} catch (Exception ex) {
				DialogoError.mostrar("Error", ex.getMessage());
			}

		} else {
			DialogoError.mostrar("Error",
					"No existen Componentes para Mostrar el Objeto");
		}

	}

	private TipoFuncion tipoFuncionActual = TipoFuncion.NINGUNA;

	private String nombreFuncionActual = "";

	public void activarCambios(TipoFuncion funcion, String nombre) {

		String nombreClase = objeto.getClass().getName();

		if (paneles.containsKey(nombreClase)) {

			tipoFuncionActual = funcion;
			nombreFuncionActual = nombre;

			ComponenteDatosListener componenteDatos = paneles.get(nombreClase);

			try {

				if (funcion == TipoFuncion.INCLUIR) {
					componenteDatos.onIncluir(objeto);
				} else if (funcion == TipoFuncion.MODIFICAR) {
					componenteDatos.onModificar(objeto);
				} else if (funcion == TipoFuncion.DEFINIDA_USUARIO) {
					componenteDatos.onFuncionPersonalizada(objeto, funcion,
							nombre);
				}

				cambiarEstadoBotones(true);

			} catch (ObeliscoException obex) {
				if (obex.getNumError() > 0) {
					DialogoError.mostrar("Error", obex.getNumError());
				} else {
					DialogoError.mostrar("Error", obex.getMessage());
				}
			} catch (Exception ex) {
				DialogoError.mostrar("Error", ex.getMessage());
			}
		}

	}

	public void onConfirmarCambios() {
		String nombreClase = objeto.getClass().getName();

		if (paneles.containsKey(nombreClase)) {

			ComponenteDatosListener componenteDatos = paneles.get(nombreClase);

			try {

				if (componenteDatos.onValidarDatos(objeto, tipoFuncionActual,
						nombreFuncionActual)) {
					componenteDatos.onConfirmarCambios(objeto,
							tipoFuncionActual, nombreFuncionActual);
				}

				cambiarEstadoBotones(false);
				tipoFuncionActual = TipoFuncion.NINGUNA;
				nombreFuncionActual = "";

				distribuirOnConfirmar();

			} catch (ObeliscoException obex) {
				if (obex.getNumError() > 0) {
					DialogoError.mostrar("Error", obex.getNumError());
				} else {
					DialogoError.mostrar("Error", obex.getMessage());
				}
			} catch (Exception ex) {
				DialogoError.mostrar("Error", ex.getMessage());
			}

		}

	}

	public void onCancelar() {

		try {

			String nombreClase = objeto.getClass().getName();

			if (paneles.containsKey(nombreClase)) {

				ComponenteDatosListener componenteDatos = paneles
						.get(nombreClase);

				componenteDatos.onCancelar();
				// cambiarEstadoBotones(false);

			}

			if (tipoFuncionActual == TipoFuncion.INCLUIR) {
				onObjetoEntidad(this.objetoAnterior);
			}

			tipoFuncionActual = TipoFuncion.NINGUNA;
			nombreFuncionActual = "";

		} catch (ObeliscoException obex) {
			DialogoError.mostrar("Error", obex.getNumError());
		} catch (Exception ex) {
			DialogoError.mostrar("Error", ex.getMessage());
		}

	}

	public void addPaneDatosListener(PaneDatosListener l) {
		listeners.add(l);
	}

	public void removePaneDatosListener(PaneDatosListener l) {
		listeners.remove(l);
	}

	private void distribuirOnConfirmar() {

		for (PaneDatosListener l : listeners) {
			l.onConfirmarCambios();
		}

	}

	public Map<String, ComponenteDatosListener> getPaneles() {
		return paneles;
	}

	public void setPaneles(Map<String, ComponenteDatosListener> paneles) {
		this.paneles = paneles;
	}

	private void onConfirmarCambios(ActionEvent e) {
		// TODO Implement.
		onConfirmarCambios();
	}

	private void onCancelar(ActionEvent e) {
		// TODO Implement.
		onCancelar();
	}

	/**
	 * Configures initial state of component. WARNING: AUTO-GENERATED METHOD.
	 * Contents will be overwritten.
	 */
	private void initComponents() {
		SplitPane splitPane1 = new SplitPane();
		splitPane1.setOrientation(SplitPane.ORIENTATION_VERTICAL_BOTTOM_TOP);
		splitPane1.setSeparatorPosition(new Extent(40, Extent.PX));
		add(splitPane1);
		Row row1 = new Row();
		row1.setAlignment(new Alignment(Alignment.RIGHT, Alignment.CENTER));
		row1.setCellSpacing(new Extent(5, Extent.PX));
		splitPane1.add(row1);
		btnAceptar = new Button();
		btnAceptar.setStyleName("Obelisco.Boton.Aceptar");
		btnAceptar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				onConfirmarCambios(e);
			}
		});
		row1.add(btnAceptar);
		btnCancelar = new Button();
		btnCancelar.setStyleName("Obelisco.Boton.Cancelar");
		btnCancelar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				onCancelar(e);
			}
		});
		row1.add(btnCancelar);
		paneContenido = new ContainerEx();
		paneContenido.setWidth(new Extent(100, Extent.PERCENT));
		paneContenido.setHeight(new Extent(99, Extent.PERCENT));
		splitPane1.add(paneContenido);
	}
}
